package com.zhiyou100.test.test04.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author yang
 * @className Demo02
 * @packageName com.zhiyou100.test.test04.proxy
 * @Description TODO 动态代理
 * @date 2020-08-11 10:20
 */
public class Demo02 {
    public static void main(String[] args) {
        final Worker wang = new Worker("王", 38);

        final ProxyFactory proxyFactory = new ProxyFactory(wang);
        final WorkerInterface instance = (WorkerInterface) proxyFactory.getInstance();
        System.out.println(instance);


    }
}


/**
 * 1 创建一个代理工厂类，实现接口 InvocationHandler
 */
class ProxyFactory implements InvocationHandler {
    /**
     * 2 定义成员变量，记录 被代理对象
     */
    private Object target;

    /**
     * 3 通过构造方法赋值
     *
     * @param target
     */
    ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     * @Description 4 实现 invoke 方法，对目标对象的方法进行控制 代理对象的方法被调用会执行
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //System.out.println("proxy = " + proxy);

        System.out.println("目标对象方法调用前的：： 预处理代码块");
        final Object invoke = method.invoke(target, args);
        System.out.println("目标对象方法调用后的：： 预处理代码块");
        return invoke;
    }

    /**
     * 5 定义一个方法 getInstance 来动态的创建代理对象
     *
     * @return
     */
    public Object getInstance() {

        /*
         * static Object	newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
         *
         * ClassLoader loader   代理对象的类加载器
         * Class<?>[] interfaces    代理对象的所有接口
         * InvocationHandler h  InvocationHandler 的实现类对象
         *
         */

        Object proxy = Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this

        );
        return proxy;
    }
}

/**
 * 6 定义被代理类 必须实现接口
 */
class Worker implements WorkerInterface {
    String name;
    int age;
    @Override
    public void show(){
        System.out.println("我是一名工人"+name+" age = "+age);
    }

    @Override
    public void work(){
        System.out.println("工人"+name+" 正在工作");
    }

    public Worker() {
    }

    public Worker(String name, int age) {
        this.name = name;
        this.age = age;
    }
}